#ifndef GAME_H
#define GAME_H

#include <QWidget>
#include <QLabel>
#include <QMessageBox>
#include <QPainter>
#include <QKeyEvent>
#include <QPushButton>
#include <QMouseEvent>

#include <string>
#include <vector>
#include <memory>

#include "snake.h"
#include "snakehead.h"

class Game;

class mGameWidget:public QWidget{
friend class Game;
public:
    using QWidget::QWidget;
    //mGameWidget(QWidget* parent);
    void setHead(SnakeHead);
    void initsnake();
    void moveToMouse(int x, int y);

    void paintEvent(QPaintEvent*);
    void mousePressEvent(QMouseEvent*);
private:
    std::unique_ptr<Snake> mPtrSnake;
    QPainter painter;
    QColor color;
    QPen pen;
    const int BodyWidth = 25;
    const int BodyHeight = 30;
    SnakeBody mFood;
    SnakeHead mHead;
    double speed = 1;
};

class Game:public QWidget
{
friend class mGameWidget;
public:
    Game(QWidget*, SnakeHead);
    QSize sizeHint() const;
    ~Game();
		
    void loadLeadBoard();
    void updateLeadBoard();
    bool readLeaderBoard();
    bool updateLeaderBoard();
    bool writeLeaderBoard();
    void renderLeaderBoard() const;
    
    void renderBoards() const;
    
    void initializeGame();
    void runGame();
    void renderPoints() const;
    void renderDifficulty() const;
    
    void createRamdonFood();
    void controlSnake() const;

    int renderRestartMenu() const;
    void adjustDelay();
    

private:
    // We need to have two windows
    // One is for game introduction
    // One is for game mWindows
    int mScreenWidth;
    int mScreenHeight;
    int mGameBoardWidth;
    int mGameBoardHeight;
    const int mInformationHeight = 180;
    const int mInstructionWidth = 540;
    QWidget* mParentWidget;
    QWidget* mInformationBoard;
    mGameWidget* mGameBoard;

    const int mTextHeight = 20;
    // Snake information
    const int mInitialSnakeLength = 2;
    SnakeHead mSnakeHead;
    // Food information
    SnakeBody mFood;
    const char mFoodSymbol = '#';
    int mPoints = 0;
    int mDifficulty = 0;
    int mBaseDelay = 20;
    int mDelay;
    const std::string mRecordBoardFilePath = "record.dat";
    std::vector<int> mLeaderBoard;
    const int mNumLeaders = 3;

public slots:
    void startGame();
};

#endif
